package com.zkflzl.mianshi.service;

import com.zkflzl.mianshi.common.ErrorCode;
import com.zkflzl.mianshi.exception.BusinessException;
import com.zkflzl.mianshi.model.enums.ViewContentTypeEnum;
import com.zkflzl.mianshi.utils.MyFileUtils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.net.URL;

import static com.zkflzl.mianshi.constant.MinioConstant.MINIO_BUCKET;
import static com.zkflzl.mianshi.constant.MinioConstant.MINIO_ENDPOINT;

/**
 * @Author：zhangke
 */
@Service
@Slf4j
public class MinioService {

    @Resource
    private MinioClient minioClient;
    /**
     * 文件上传
     *
     * @param file     文件
     * @param fileName 拼接后的文件名
     */
    public String uploadFile(MultipartFile file, String fileName) {
        // 校验当前文件名是否包含,
        if (fileName.contains(",")) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件名不能包含逗号");
        }

        try (InputStream in = file.getInputStream()) {
            String contentType = ViewContentTypeEnum.getContentType(fileName);
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(MINIO_BUCKET)
                            .object(fileName)
                            .stream(in, in.available(), -1)
                            .contentType(contentType)
                            .build()
            );
            // 生成公开访问的 URL
            URL fileUrl = new URL(MINIO_ENDPOINT + "/" + MINIO_BUCKET + "/" + fileName);

            // 返回文件 URL
            return fileUrl.toString();
        } catch (Exception e) {
            log.error("文件上传失败: {}", e.getMessage(), e); // 记录详细异常信息
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "文件上传失败: " + e.getMessage());
        }
    }

    // 上传头像
    public String uploadAvatar(MultipartFile image, Long userId) {
        // 校验图片格式是否符合
        if (MyFileUtils.isNotValidImage(image)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "图片格式错误");
        }
        long time = System.currentTimeMillis();
        String fileName = image.getOriginalFilename();
        fileName = "user/avatar/" + userId + "/" + time + "/" + fileName;
        return uploadFile(image, fileName);
    }

    // 上传题库图片
    public String uploadBankImg(MultipartFile image, Long questionBankId) {
        // 校验图片格式是否符合
        if (MyFileUtils.isNotValidImage(image)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "图片格式错误");
        }
        long time = System.currentTimeMillis();
        String fileName = image.getOriginalFilename();
        fileName = "question/bank/img/" + questionBankId + "/" + time + "/" + fileName;
        return uploadFile(image, fileName);
    }

    public void delFile(String minioBucket, String filePath) {
        try {
            // 提取对象路径
            String objectPath = extractObjectPath(filePath);
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(minioBucket)
                            .object(objectPath)
                            .build()
            );
        } catch (Exception e) {
            log.error("删除文件失败:{}", filePath, e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除文件失败");
        }
    }
    private String extractObjectPath(String filePath) throws Exception {
        URL url = new URL(filePath);
        String path = url.getPath();
        // 去掉存储桶名称
        if (path.startsWith("/" + MINIO_BUCKET + "/")) {
            return path.substring(("/" + MINIO_BUCKET + "/").length());
        } else {
            throw new Exception("无效的文件路径: " + filePath);
        }
    }
}
